package org.groovymud.object.combat;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import junit.framework.TestCase;

import org.groovymud.object.MudObject;
import org.groovymud.object.alive.AbstractMOB;
import org.groovymud.object.alive.Alive;
import org.groovymud.object.guild.AbstractGuildBehaviour;
import org.groovymud.object.guild.skill.Skill;
import org.groovymud.object.guild.skill.SkillTreeDecorator;
import org.groovymud.object.race.AbstractBodyPart;
import org.groovymud.object.race.AbstractRace;
import org.groovymud.object.race.Statistics;
import org.groovymud.utils.Dice;

public class CombatBehaviourIntegrationTest extends TestCase {

    public void testFight() throws InterruptedException {

        Set attacks = new HashSet();
        attacks.add(createAttack());
        attacks.add(createAttack());

        Set targetAttacks = new HashSet();
        attacks.add(createAttack());
        Set targetAttacks2 = new HashSet();
        attacks.add(createAttack());
        AbstractMOB mob = createMOB(attacks);
        AbstractMOB target = createMOB(targetAttacks);
        AbstractMOB target2 = createMOB(targetAttacks2);

        mob.getGuildBehaviour().getCombatBehaviour().addTarget(target);
        mob.getGuildBehaviour().getCombatBehaviour().addTarget(target2);
        ThreadGroup tg = new ThreadGroup("test");

        TestMob mThread = new TestMob(tg, "test");

        mThread.mob = mob;
        mThread.start();

        while (tg.activeCount() > 0) {
            Thread.sleep(100);
        }
    }

    class TestMob extends Thread {

        AbstractMOB mob;

        public TestMob(ThreadGroup tg, String name) {
            super(tg, name);
        }

        @Override
        public void run() {
            int t = 0;
            while (t < 100) {
                mob.getGuildBehaviour().getCombatBehaviour().fight();
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                t++;
            }
        }

    }

    private AbstractMOB createMOB(final Set attacks) {

        AbstractRace race = new AbstractRace() {

            @Override
            public void generateStats() {
                // TODO Auto-generated method stub

                Statistics stats = new Statistics();
                stats.setIntelligence(10);
                stats.setStrength(10);
                stats.setWisdom(10);
                stats.setDexterity(18);
                stats.setConstitution(10);
                setStatistics(stats);
            }

            @Override
            public AbstractBodyPart getHitBodyPart(int roll) {
                // TODO Auto-generated method stub
                AbstractBodyPart part = new AbstractBodyPart() {

                    @Override
                    public void doHeartBeat() {
                        // TODO Auto-generated method stub

                    }

                };
                return part;
            }

            @Override
            public List<String> getRaceCommands() {
                // TODO Auto-generated method stub
                return null;
            }

            @Override
            protected void modifyStatistics(Statistics moddedStats) {
                // TODO Auto-generated method stub

            }

        };
        AbstractMOB mob = new AbstractMOB() {

            @Override
            public long doDefend(AbstractAttack nextAttack, long damage, long attackToHit, long roll) {
                // TODO Auto-generated method stub
                return 0;
            }

            @Override
            public void doHeartBeat() {
                // TODO Auto-generated method stub

            }

            @Override
            public Set<AbstractAttack> getAttacks() {
                // TODO Auto-generated method stub
                return attacks;
            }

            @Override
            public long defend(AbstractAttack attack, long damage, long attackToHit, long roll) {
                // TODO Auto-generated method stub
                return 0;
            }
        };
        final CombatBehaviour test = new CombatBehaviour(mob) {

            @Override
            protected void sendMessage(Alive attacker, String srcMessage, String roomMessage) {
                // TODO Auto-generated method stub
                System.out.println(roomMessage);
            }
        };

        mob.setName("mob" + mob.toString());
        AbstractGuildBehaviour guild = new AbstractGuildBehaviour(mob) {

            @Override
            public void progressSkillTree(SkillTreeDecorator skilltree, String skillLongName, long valueDelta) {
                // TODO Auto-generated method stub

            }

            @Override
            public Skill getSkill(String skillLongName) {
                Skill k = new Skill(skillLongName, 10);
                return k;
            }

            @Override
            public CombatBehaviour getCombatBehaviour() {
                // TODO Auto-generated method stub
                return test;
            }
        };
        mob.setRaceBehaviour(race);
        mob.setGuildBehaviour(guild);
        return mob;
    }

    private Object createAttack() {
        // TODO Auto-generated method stub
        Dice die = new Dice(2, 6);
        AbstractAttack attack = new AbstractAttack(die) {

            @Override
            public void hit(Alive attacker, MudObject target, long damage, long attackToHit, long roll) {
                // TODO Auto-generated method stub
                System.out.println(target.getName() + " was hit:" + damage + ", tohit:" + attackToHit + " roll: " + roll);
            }

            @Override
            public void miss(Alive attacker, MudObject nextTarget, long attackToHit, long roll) {
                // TODO Auto-generated method stub
                System.out.println(nextTarget.getName() + " was missed - attackToHit:" + attackToHit + " roll: " + roll);
            }

            @Override
            public boolean targetInRange(MudObject nextTarget) {
                // TODO Auto-generated method stub
                return true;
            }

        };
        return attack;
    }

}
